
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/select.h>
#include <sys/time.h>
#include <errno.h>
#include <unistd.h>

#include <time.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>

int connect_to_server(const char * service_ip, int16_t service_port) {

    int client_fd = 0;
    // af_inet and tcp protocol
    client_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (client_fd <= 0) {

        printf("create socket fd failure.\n");
        return -1;
    }
    struct sockaddr_in service_sai;
    bzero(&service_sai, sizeof(service_sai));

    service_sai.sin_family = AF_INET;
    service_sai.sin_port   = htons(service_port);
    inet_pton(AF_INET, service_ip, &service_sai.sin_addr);

    // block connect
    int connect_result = connect(client_fd, (struct sockaddr*)&service_sai, sizeof(service_sai));
    if (connect_result != 0) {

        printf("connect to service : %s failure.\n", service_ip);
        close(client_fd);
        return -1;
    }
    // success
    return client_fd;
}

int set(int fd, const char * key, const char * content) {

    char buffer[100];
    bzero(buffer, 100);
    int size = snprintf(buffer,100,"SET %s %s\r\n", key, content);

    write(fd, buffer, size);
}

int get(int client_fd, const char * key, char * recv_buffer, size_t recv_len) {

    char buffer[100];
    bzero(buffer, 100);
    int size = snprintf(buffer, 100, "GET %s\r\n", key);
    write(client_fd, buffer, size);   
 
    do {
        read(client_fd, recv_buffer, recv_len);
        char * end_ptr = strstr(recv_buffer,"\r\n");
        if (end_ptr == NULL) {

            printf("len to short \n");
            break;
        } else {
            printf("%s",recv_buffer);
            break;
        }
    } while(1);

    return 1;
}

void test_case_of_connect_to_server() {

    const char * service = "127.0.0.1";
    const int16_t  port  = 6379;

    int client_fd = connect_to_server(service, port);
    if (client_fd < 0) {

        printf("connect to service %s failure.\n", service);
    } else {

        printf("success.\n");
        set(client_fd, "hello", "world");

        char buffer[100];
        bzero(buffer, 100);
        get(client_fd, "hello", buffer, 100);
        // char buffer[10240];
        // char send_buffer[100];
        // bzero(buffer, 10240);
        // bzero(send_buffer, 100);

        // int size = snprintf(send_buffer,100,"info\r\n");
        // write(client_fd, send_buffer, size);
        
        // char * first = buffer;
        // do{

        //     read(client_fd, first, 1024);
        //     // check format
        //     char * find_ptr = strstr(first,"\r\n");
        //     if (find_ptr == NULL) {

        //         first = first + 1024;
        //     } else {

        //         printf("%s.\n",buffer);
        //     }
        // }while(1);
        // do {


        // }while(1);
        // write(client_fd, send_buffer, size);
        // read(client_fd, buffer, 5000);
        // printf("%s", buffer);
        close(client_fd);
    }
}

void test_case_of_connect_to_server_set() {

    const char * service = "127.0.0.1";
    const int16_t  port  = 6379;

    int client_fd = connect_to_server(service, port);
    if (client_fd < 0) {

        printf("connect to redis failure.\n");
        return;
    }
    fd_set read_set;
    char buffer[1500];
    for (; ; ) {

        bzero(buffer, 1500);
        FD_ZERO(&read_set);
        FD_SET(client_fd, &read_set);
        int number = select(client_fd + 1, &read_set, NULL, NULL, NULL);
        if (number <= 0) {

            break;
        }
        if (FD_ISSET(client_fd, &read_set)) {
            while(1) {
                size_t recv_size = 0;
                if ((recv_size = read(client_fd, buffer, 1500)) <= 0) {

                    printf("peer close the connection and errno %d\n", errno);
                    return;
                }
                // recv_size
                // check format
                char * end_ptr = strstr(buffer, "\r\n");
                if (end_ptr != NULL) {

                    break;
                } else {

                    
                }
            }
        }
    }
}

int main(int argc, char * argv[]) {

    test_case_of_connect_to_server();
    return EXIT_SUCCESS;
}

// gcc -Wall -Wunused -g client.c -o client